{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `override` / `final`\n",
    "\n",
    "- **`override`**：标记成员函数意在重写基类虚函数，若签名不匹配则编译错误，可防止意外隐藏。\n",
    "- **`final`**：\n",
    "  - 用在虚函数上：阻止进一步重写。\n",
    "  - 用在类上：禁止被继承。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Derived::foo\n"
     ]
    }
   ],
   "source": [
    "#include <iostream>\n",
    "\n",
    "struct Base {\n",
    "    virtual void foo() { std::cout << \"Base::foo\\n\"; }\n",
    "};\n",
    "\n",
    "struct Derived final : Base {\n",
    "    void foo() override { std::cout << \"Derived::foo\\n\"; }\n",
    "    // void bar() override; // 若签名不匹配将编译失败\n",
    "};\n",
    "\n",
    "{\n",
    "    Derived d;\n",
    "    Base& ref = d;\n",
    "    ref.foo();\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "input_line_8:6:16: error: only virtual member functions can be marked 'override'\n",
      "    void bar() override; // 若签名不匹配将编译失败\n",
      "               ^~~~~~~~\n"
     ]
    },
    {
     "ename": "Interpreter Error",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "Interpreter Error: "
     ]
    }
   ],
   "source": [
    "#include <iostream>\n",
    "\n",
    "struct Base {\n",
    "    virtual void foo() { std::cout << \"Base::foo\\n\"; }\n",
    "};\n",
    "\n",
    "struct Derived final : Base {\n",
    "    void bar() override; // 若签名不匹配将编译失败\n",
    "};\n",
    "\n",
    "{\n",
    "    Derived d;\n",
    "    Base& ref = d;\n",
    "    ref.foo();\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 虚函数表（vtable）与多重继承布局\n",
    "\n",
    "- 每个拥有虚函数的多态对象通常包含指向虚表的指针（vptr）。\n",
    "- 虚表列出虚函数的实现入口；\n",
    "- 多重继承下，不同基类子对象可能拥有独立的 vptr，或共享一个包含偏移信息的结构，具体由 ABI 决定。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Derived address: 0x7fffe1705d38\n",
      "Base1 subobject address: 0x7fffe1705d38\n",
      "Base2 subobject address: 0x7fffe1705d40\n",
      "Derived::f1\n",
      "Derived::f2\n"
     ]
    }
   ],
   "source": [
    "#include <iostream>\n",
    "\n",
    "struct Base1 { virtual void f1() { std::cout << \"Base1\\n\"; } };\n",
    "struct Base2 { virtual void f2() { std::cout << \"Base2\\n\"; } };\n",
    "\n",
    "struct Derived : Base1, Base2 {\n",
    "    void f1() override { std::cout << \"Derived::f1\\n\"; }\n",
    "    void f2() override { std::cout << \"Derived::f2\\n\"; }\n",
    "};\n",
    "\n",
    "{\n",
    "    Derived d;\n",
    "    Base1* b1 = &d;\n",
    "    Base2* b2 = &d;\n",
    "    std::cout << \"Derived address: \" << &d << '\\n';\n",
    "    std::cout << \"Base1 subobject address: \" << b1 << '\\n';\n",
    "    std::cout << \"Base2 subobject address: \" << b2 << '\\n';\n",
    "    b1->f1();\n",
    "    b2->f2();\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 菱形继承与虚拟继承\n",
    "\n",
    "- 普通菱形继承会复制共享基类的数据，造成多份实例。\n",
    "- `virtual` 继承使得派生层次共享同一份虚拟基类子对象，消除重复。\n",
    "- 编译器通过调整指针偏移确保所有路径指向同一虚拟基对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C sees value = 42\n"
     ]
    }
   ],
   "source": [
    "#include <iostream>\n",
    "\n",
    "struct A {\n",
    "    int value = 0;\n",
    "};\n",
    "\n",
    "struct B : virtual A { };\n",
    "struct C : virtual A { };\n",
    "\n",
    "struct D : B, C { };\n",
    "\n",
    "{\n",
    "    D d;\n",
    "    B& b = d;\n",
    "    C& c = d;\n",
    "    b.value = 42;\n",
    "    std::cout << \"C sees value = \" << c.value << '\\n'; // 同一份 A\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `= delete` 与 `= default`；默认函数生成条件\n",
    "\n",
    "- **`= default`**：显式请求编译器生成默认实现，可用于声明为 `public` 或在类内外定义。\n",
    "- **`= delete`**：禁止函数生成/使用，如禁用拷贝或特定构造。\n",
    "- 默认生成函数（默认构造、拷贝/移动构造、拷贝/移动赋值、析构）只有当它们被需要且未被用户声明时自动生成；若显式 `= default`，即使有其他声明也可强制生成（若满足可行条件）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Move succeeded\n"
     ]
    }
   ],
   "source": [
    "#include <iostream>\n",
    "\n",
    "struct NonCopy {\n",
    "    NonCopy() = default;              // 使用合成默认构造\n",
    "    NonCopy(const NonCopy&) = delete; // 禁止拷贝\n",
    "    NonCopy(NonCopy&&) = default;     // 请求移动构造\n",
    "};\n",
    "\n",
    "{\n",
    "    NonCopy a;\n",
    "    NonCopy b = std::move(a); // OK\n",
    "    // NonCopy c = a;         // 编译失败：拷贝被 delete\n",
    "    std::cout << \"Move succeeded\\n\";\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "input_line_9:5:13: error: call to deleted constructor of 'NonCopy'\n",
      "    NonCopy c = a;         // 编译失败：拷贝被 delete\n",
      "            ^   ~\n",
      "input_line_8:3:5: note: 'NonCopy' has been explicitly marked deleted here\n",
      "    NonCopy(const NonCopy&) = delete; // 禁止拷贝\n",
      "    ^\n"
     ]
    },
    {
     "ename": "Interpreter Error",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "Interpreter Error: "
     ]
    }
   ],
   "source": [
    "{\n",
    "    NonCopy a;\n",
    "    NonCopy b = std::move(a); // OK\n",
    "    NonCopy c = a;         // 编译失败：拷贝被 delete\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 移动语义、右值引用、`std::move`\n",
    "\n",
    "- **右值引用 (`T&&`)** 捕获临时资源，使函数能够“窃取”其内部资源。\n",
    "- **`std::move`**：纯转换，把参数无条件转换为右值引用，触发移动重载；本身不移动数据。\n",
    "- 配合移动构造/赋值可避免昂贵的深拷贝。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Move ctor\n",
      "a data size after move = 0\n",
      "b data size = 1000\n"
     ]
    }
   ],
   "source": [
    "#include <iostream>\n",
    "#include <utility>\n",
    "#include <vector>\n",
    "\n",
    "struct Buffer {\n",
    "    std::vector<int> data;\n",
    "    Buffer(size_t n) : data(n, 42) {}\n",
    "    Buffer(Buffer&& other) noexcept : data(std::move(other.data)) {\n",
    "        std::cout << \"Move ctor\\n\";\n",
    "    }\n",
    "    Buffer(const Buffer&) = delete;\n",
    "};\n",
    "\n",
    "{\n",
    "    Buffer a(1000);\n",
    "    Buffer b(std::move(a)); // 触发移动构造\n",
    "    std::cout << \"a data size after move = \" << a.data.size() << '\\n';\n",
    "    std::cout << \"b data size = \" << b.data.size() << '\\n';\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 拷贝省略与强制性复制省略（C++17）\n",
    "\n",
    "- **拷贝省略**：编译器可省掉临时对象到目标对象的拷贝/移动（如返回局部、throw 表达式等）。\n",
    "- **强制性复制省略（C++17 起）**：在以下场景必须直接构造目标对象，无需可用的拷贝/移动：\n",
    "  1. `return` 返回同类型临时（NRVO/PRVO）。\n",
    "  2. `throw` 抛出同类型临时。\n",
    "  3. `co_return` 类似情况。\n",
    "- 因强制省略，返回临时可在无拷贝/移动构造函数时依然合法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "\n",
    "struct Widget {\n",
    "    Widget() { std::cout << \"Widget()\\n\"; }\n",
    "    Widget(const Widget&) = delete;\n",
    "    Widget(Widget&&) = delete;\n",
    "};"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Widget()\n",
      "constructed without copy/move\n"
     ]
    }
   ],
   "source": [
    "Widget make_widget() {\n",
    "    return Widget(); // C++17 起强制性复制省略，OK\n",
    "}\n",
    "\n",
    "{\n",
    "    Widget w = make_widget();\n",
    "    std::cout << \"constructed without copy/move\\n\";\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如需深入观察，可使用编译器选项（如 `-fdump-class-hierarchy` 或 `-fno-elide-constructors`）进一步研究对象布局与优化行为。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
